

class Node {
    private Object item;
    private Node left;
    private Node right;

    public Node(Object item) {
	this(item, null, null);
    }
    public Node(Object item, Node left, Node right) {
	this.item = item;
	this.left = left;
	this.right = right;
    }
    private void visit() {
	System.out.print(item + " ");
    }
    public void preorder() {
	visit();
	if (left != null)
	    left.preorder();
	if (right != null)
	    right.preorder();
    }
    public void postorder() {
	if (left != null)
	    left.postorder();
	if (right != null)
	    right.postorder();
	visit();
    }
    public void inorder() {
	if (left != null)
	    left.inorder();
	visit();
	if (right != null)
	    right.inorder();
    }
    public int evaluate() {
	String item = (String)this.item;
	int value = 0;
	if (Character.isDigit(item.charAt(0)))
	    value = Integer.parseInt(item);
	else {
	    int lval = left.evaluate();
	    int rval = right.evaluate();
	    if (item.equals("+"))
		value = lval + rval;
	    else if (item.equals("-"))
		value = lval - rval;
	    else if (item.equals("*"))
		value = lval * rval;
	    else if (item.equals("/"))
		value = lval / rval;
	}
	return value;
    }
    private static boolean[] regs = {true, true, true, true};
    private int allocReg() {
	int i;
	for (i = 0; i < regs.length; i++)
	    if (regs[i] == true)
		break;
	regs[i] = false;
	return i;
    }
    private void freeReg(int reg) {
	regs[reg] = true;
    }
    public int code() {
	String item = (String)this.item;
	int register;
	if (Character.isDigit(item.charAt(0))) {
	    int value = Integer.parseInt(item);
	    register = allocReg();
	    System.out.println("ld" + " " + "r"+register + " " + value);
	} else {
	    String opcode = null;
	    if (item.equals("+"))
		opcode = "add";
	    else if (item.equals("-"))
		opcode = "sub";
	    else if (item.equals("*"))
		opcode = "mul";
	    else if (item.equals("/"))
		opcode = "div";
	    int lreg = left.code();
	    int rreg = right.code();
	    register = allocReg();
	    System.out.println(opcode + " " + "r"+register + " " + "r"+lreg + " " + "r"+rreg);
	    freeReg(lreg);
	    freeReg(rreg);
	}
	return register;
    }
}

class ExprTree {
    public static Node makeTree() {
	return
	    new Node("*",
		     new Node("+", 
			      new Node("*",
				       new Node("2"),
				       new Node("4")
				       ),
			      new Node("/",
				       new Node("8"),
				       new Node("4")
				       )
			      ),
		     new Node("-",
			      new Node("2"),
			      new Node("4")
			      )
		     );
    }

    public static void main(String[] args) {
	Node tree = makeTree();
	System.out.println("PREorder");
	tree.preorder();
	System.out.println();
	System.out.println("POSTorder");
	tree.postorder();
	System.out.println();
	System.out.println("INorder");
	tree.inorder();
	System.out.println();
	System.out.println("EVAL");
	System.out.println(tree.evaluate());
	System.out.println("CODE");
	System.out.println(tree.code());
    }
}


